"""
自定义编码中间件，确保所有响应都使用UTF-8编码
"""
import json
from django.utils.deprecation import MiddlewareMixin
from django.http import JsonResponse


class UTF8EncodingMiddleware(MiddlewareMixin):
    """
    确保所有响应都使用UTF-8编码，避免Unicode字符导致的编码问题
    """
    
    def process_response(self, request, response):
        # 只处理JSON响应
        if isinstance(response, JsonResponse):
            try:
                # 获取响应内容
                content = response.content.decode('utf-8')
                
                # 尝试解析JSON
                data = json.loads(content)
                
                # 递归处理JSON中的所有字符串，确保Unicode字符被正确处理
                def safe_encode_strings(obj):
                    if isinstance(obj, str):
                        # 确保字符串是UTF-8编码，移除或替换有问题的Unicode字符
                        try:
                            # 尝试编码为UTF-8，如果有问题则使用errors='ignore'
                            return obj.encode('utf-8', errors='ignore').decode('utf-8')
                        except (UnicodeError, UnicodeEncodeError, UnicodeDecodeError):
                            # 如果仍有问题，返回安全的字符串
                            return "编码错误"
                    elif isinstance(obj, dict):
                        return {key: safe_encode_strings(value) for key, value in obj.items()}
                    elif isinstance(obj, list):
                        return [safe_encode_strings(item) for item in obj]
                    else:
                        return obj
                
                # 处理数据中的字符串
                safe_data = safe_encode_strings(data)
                
                # 重新创建响应
                response = JsonResponse(safe_data, safe=False)
                
            except (json.JSONDecodeError, UnicodeError, UnicodeEncodeError, UnicodeDecodeError):
                # 如果处理失败，保持原响应不变
                pass
        
        # 确保响应头包含正确的编码信息
        if 'Content-Type' in response:
            if 'charset=' not in response['Content-Type']:
                response['Content-Type'] += '; charset=utf-8'
        else:
            response['Content-Type'] = 'application/json; charset=utf-8'
        
        return response
